{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7e970772",
   "metadata": {},
   "source": [
    "# Chapter 2 - Production (Python Code)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fd1d49bf",
   "metadata": {
    "tags": [
     "hide-output"
    ]
   },
   "outputs": [],
   "source": [
    "! pip install --upgrade quantecon_book_networks"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5bb0e40f",
   "metadata": {},
   "source": [
    "We begin with some imports."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b06f1ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "import quantecon as qe\n",
    "import quantecon_book_networks\n",
    "import quantecon_book_networks.input_output as qbn_io\n",
    "import quantecon_book_networks.plotting as qbn_plt\n",
    "import quantecon_book_networks.data as qbn_data\n",
    "ch2_data = qbn_data.production()\n",
    "default_figsize = (6, 4)\n",
    "export_figures = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67d26617",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib.cm as cm\n",
    "import matplotlib.colors as plc\n",
    "from matplotlib import cm\n",
    "quantecon_book_networks.config(\"matplotlib\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aa98eb15",
   "metadata": {},
   "source": [
    "## Multisector Models\n",
    "\n",
    "We start by loading a graph of linkages between 15 US sectors in 2021. \n",
    "\n",
    "Our graph comes as a list of sector codes, an adjacency matrix of sales between\n",
    "the sectors, and a list the total sales of each sector.  \n",
    "\n",
    "In particular, `Z[i,j]` is the sales from industry `i` to industry `j`, and `X[i]` is the the total sales\n",
    "of each sector `i`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bac5b180",
   "metadata": {},
   "outputs": [],
   "source": [
    "codes = ch2_data[\"us_sectors_15\"][\"codes\"]\n",
    "Z = ch2_data[\"us_sectors_15\"][\"adjacency_matrix\"]\n",
    "X = ch2_data[\"us_sectors_15\"][\"total_industry_sales\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c3a07fd9",
   "metadata": {},
   "source": [
    "Now we define a function to build coefficient matrices. \n",
    "\n",
    "Two coefficient matrices are returned. The backward linkage case, where sales\n",
    "between sector `i` and `j` are given as a fraction of total sales of sector\n",
    "`j`. The forward linkage case, where sales between sector `i` and `j` are\n",
    "given as a fraction of total sales of sector `i`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fa4c9d05",
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_coefficient_matrices(Z, X):\n",
    "    \"\"\"\n",
    "    Build coefficient matrices A and F from Z and X via \n",
    "    \n",
    "        A[i, j] = Z[i, j] / X[j] \n",
    "        F[i, j] = Z[i, j] / X[i]\n",
    "    \n",
    "    \"\"\"\n",
    "    A, F = np.empty_like(Z), np.empty_like(Z)\n",
    "    n = A.shape[0]\n",
    "    for i in range(n):\n",
    "        for j in range(n):\n",
    "            A[i, j] = Z[i, j] / X[j]\n",
    "            F[i, j] = Z[i, j] / X[i]\n",
    "\n",
    "    return A, F\n",
    "\n",
    "A, F = build_coefficient_matrices(Z, X)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66ecec7b",
   "metadata": {},
   "source": [
    "### Backward linkages for 15 US sectors in 2021\n",
    "\n",
    "Here we calculate the hub-based eigenvector centrality of our backward linkage coefficient matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f1e25af6",
   "metadata": {},
   "outputs": [],
   "source": [
    "centrality = qbn_io.eigenvector_centrality(A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "99a5def5",
   "metadata": {},
   "source": [
    "Now we use the `quantecon_book_networks` package to produce our plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c9a1c8e",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(8, 10))\n",
    "plt.axis(\"off\")\n",
    "color_list = qbn_io.colorise_weights(centrality, beta=False)\n",
    "# Remove self-loops\n",
    "A1 = A.copy()\n",
    "for i in range(A1.shape[0]):\n",
    "    A1[i][i] = 0\n",
    "qbn_plt.plot_graph(A1, X, ax, codes, \n",
    "              layout_type='spring',\n",
    "              layout_seed=5432167,\n",
    "              tol=0.0,\n",
    "              node_color_list=color_list) \n",
    "\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "30667357",
   "metadata": {},
   "source": [
    "### Eigenvector centrality of across US industrial sectors\n",
    "\n",
    "Now we plot a bar chart of hub-based eigenvector centrality by sector."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60e3a77c",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=default_figsize)\n",
    "ax.bar(codes, centrality, color=color_list, alpha=0.6)\n",
    "ax.set_ylabel(\"eigenvector centrality\", fontsize=12)\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_ec.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0556d61",
   "metadata": {},
   "source": [
    "### Output multipliers across 15 US industrial sectors\n",
    "\n",
    "Output multipliers are equal to the authority-based Katz centrality measure of\n",
    "the backward linkage coefficient matrix. \n",
    "\n",
    "Here we calculate authority-based\n",
    "Katz centrality using the `quantecon_book_networks` package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f1358ad2",
   "metadata": {},
   "outputs": [],
   "source": [
    "omult = qbn_io.katz_centrality(A, authority=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d45c83f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=default_figsize)\n",
    "omult_color_list = qbn_io.colorise_weights(omult,beta=False)\n",
    "ax.bar(codes, omult, color=omult_color_list, alpha=0.6)\n",
    "ax.set_ylabel(\"Output multipliers\", fontsize=12)\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_omult.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d07a87b3",
   "metadata": {},
   "source": [
    "### Forward linkages and upstreamness over US industrial sectors\n",
    "\n",
    "Upstreamness is the hub-based Katz centrality of the forward linkage\n",
    "coefficient matrix. \n",
    "\n",
    "Here we calculate hub-based Katz centrality."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2df63367",
   "metadata": {},
   "outputs": [],
   "source": [
    "upstreamness = qbn_io.katz_centrality(F)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cff33a99",
   "metadata": {},
   "source": [
    "Now we plot the network."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8ac45508",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(8, 10))\n",
    "plt.axis(\"off\")\n",
    "upstreamness_color_list = qbn_io.colorise_weights(upstreamness,beta=False)\n",
    "# Remove self-loops\n",
    "for i in range(F.shape[0]):\n",
    "    F[i][i] = 0\n",
    "qbn_plt.plot_graph(F, X, ax, codes, \n",
    "              layout_type='spring', # alternative layouts: spring, circular, random, spiral\n",
    "              layout_seed=5432167,\n",
    "              tol=0.0,\n",
    "              node_color_list=upstreamness_color_list) \n",
    "\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_fwd.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e9cbc94b",
   "metadata": {},
   "source": [
    "### Relative upstreamness of US industrial sectors\n",
    "\n",
    "Here we produce a barplot of upstreamness."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abc67147",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=default_figsize)\n",
    "ax.bar(codes, upstreamness, color=upstreamness_color_list, alpha=0.6)\n",
    "ax.set_ylabel(\"upstreamness\", fontsize=12)\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_up.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9223fd5",
   "metadata": {},
   "source": [
    "### Hub-based Katz centrality of across 15 US industrial sectors\n",
    "\n",
    "Next we plot the hub-based Katz centrality of the backward linkage coefficient matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19bce52b",
   "metadata": {},
   "outputs": [],
   "source": [
    "kcentral = qbn_io.katz_centrality(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7563381",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=default_figsize)\n",
    "kcentral_color_list = qbn_io.colorise_weights(kcentral,beta=False)\n",
    "ax.bar(codes, kcentral, color=kcentral_color_list, alpha=0.6)\n",
    "ax.set_ylabel(\"Katz hub centrality\", fontsize=12)\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_katz.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf61ce72",
   "metadata": {},
   "source": [
    "### The Leontief inverse 𝐿 (hot colors are larger values)\n",
    "\n",
    "We construct the Leontief inverse matrix from 15 sector adjacency matrix."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "87c25e09",
   "metadata": {},
   "outputs": [],
   "source": [
    "I = np.identity(len(A))\n",
    "L = np.linalg.inv(I - A)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a37cada4",
   "metadata": {},
   "source": [
    "Now we produce the plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d590c0e1",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(6.5, 5.5))\n",
    "\n",
    "ticks = range(len(L))\n",
    "\n",
    "levels = np.sqrt(np.linspace(0, 0.75, 100))\n",
    "\n",
    "co = ax.contourf(ticks, \n",
    "                    ticks,\n",
    "                    L,\n",
    "                    levels,\n",
    "                    alpha=0.85, cmap=cm.plasma)\n",
    "\n",
    "ax.set_xlabel('sector $j$', fontsize=12)\n",
    "ax.set_ylabel('sector $i$', fontsize=12)\n",
    "ax.set_yticks(ticks)\n",
    "ax.set_yticklabels(codes)\n",
    "ax.set_xticks(ticks)\n",
    "ax.set_xticklabels(codes)\n",
    "\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_leo.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1a9a7d40",
   "metadata": {},
   "source": [
    "### Propagation of demand shocks via backward linkages\n",
    "\n",
    "We begin by generating a demand shock vector $d$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0861b2f5",
   "metadata": {},
   "outputs": [],
   "source": [
    "N = len(A)\n",
    "np.random.seed(1234)\n",
    "d = np.random.rand(N) \n",
    "d[6] = 1  # positive shock to agriculture"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fa2840f",
   "metadata": {},
   "source": [
    "Now we simulate the demand shock propagating through the economy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9089f879",
   "metadata": {},
   "outputs": [],
   "source": [
    "sim_length = 11\n",
    "x = d\n",
    "x_vecs = []\n",
    "for i in range(sim_length):\n",
    "    if i % 2 ==0:\n",
    "        x_vecs.append(x)\n",
    "    x = A @ x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a51906c",
   "metadata": {},
   "source": [
    "Finally, we plot the shock propagating through the economy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d777b13",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(3, 2, figsize=(8, 10))\n",
    "axes = axes.flatten()\n",
    "\n",
    "for ax, x_vec, i in zip(axes, x_vecs, range(sim_length)):\n",
    "    if i % 2 != 0:\n",
    "        pass\n",
    "    ax.set_title(f\"round {i*2}\")\n",
    "    x_vec_cols = qbn_io.colorise_weights(x_vec,beta=False)\n",
    "    # remove self-loops\n",
    "    for i in range(len(A)):\n",
    "        A[i][i] = 0\n",
    "    qbn_plt.plot_graph(A, X, ax, codes,\n",
    "                  layout_type='spring',\n",
    "                  layout_seed=342156,\n",
    "                  node_color_list=x_vec_cols,\n",
    "                  node_size_multiple=0.00028,\n",
    "                  edge_size_multiple=0.8)\n",
    "\n",
    "plt.tight_layout()\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_15_shocks.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ccd313f",
   "metadata": {},
   "source": [
    "### Network for 71 US sectors in 2021\n",
    "\n",
    "We start by loading a graph of linkages between 71 US sectors in 2021."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "24d32882",
   "metadata": {},
   "outputs": [],
   "source": [
    "codes_71 = ch2_data['us_sectors_71']['codes']\n",
    "A_71 = ch2_data['us_sectors_71']['adjacency_matrix']\n",
    "X_71 = ch2_data['us_sectors_71']['total_industry_sales']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e4efe0f9",
   "metadata": {},
   "source": [
    "Next we calculate our graph's properties. \n",
    "\n",
    "We use hub-based eigenvector centrality as our centrality measure for this plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c468f74b",
   "metadata": {},
   "outputs": [],
   "source": [
    "centrality_71 = qbn_io.eigenvector_centrality(A_71)\n",
    "color_list_71 = qbn_io.colorise_weights(centrality_71,beta=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37c499e0",
   "metadata": {},
   "source": [
    "Finally we produce the plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d920aca",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(10, 12))\n",
    "plt.axis(\"off\")\n",
    "# Remove self-loops\n",
    "for i in range(A_71.shape[0]):\n",
    "    A_71[i][i] = 0\n",
    "qbn_plt.plot_graph(A_71, X_71, ax, codes_71,\n",
    "              node_size_multiple=0.0005,\n",
    "              edge_size_multiple=4.0,\n",
    "              layout_type='spring',\n",
    "              layout_seed=5432167,\n",
    "              tol=0.01,\n",
    "              node_color_list=color_list_71)\n",
    "\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_71.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "419a96fa",
   "metadata": {},
   "source": [
    "###  Network for 114 Australian industry sectors in 2020\n",
    "\n",
    "Next we load a graph of linkages between 114 Australian sectors in 2020."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "52309e87",
   "metadata": {},
   "outputs": [],
   "source": [
    "codes_114 = ch2_data['au_sectors_114']['codes']\n",
    "A_114 = ch2_data['au_sectors_114']['adjacency_matrix']\n",
    "X_114 = ch2_data['au_sectors_114']['total_industry_sales']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5e46835",
   "metadata": {},
   "source": [
    "Next we calculate our graph's properties. \n",
    "\n",
    "We use hub-based eigenvector centrality as our centrality measure for this plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9555ffa8",
   "metadata": {},
   "outputs": [],
   "source": [
    "centrality_114 = qbn_io.eigenvector_centrality(A_114)\n",
    "color_list_114 = qbn_io.colorise_weights(centrality_114,beta=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b6801cd",
   "metadata": {},
   "source": [
    "Finally we produce the plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1af80023",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, ax = plt.subplots(figsize=(11, 13.2))\n",
    "plt.axis(\"off\")\n",
    "# Remove self-loops\n",
    "for i in range(A_114.shape[0]):\n",
    "    A_114[i][i] = 0\n",
    "qbn_plt.plot_graph(A_114, X_114, ax, codes_114,\n",
    "              node_size_multiple=0.008,\n",
    "              edge_size_multiple=5.0,\n",
    "              layout_type='spring',\n",
    "              layout_seed=5432167,\n",
    "              tol=0.03,\n",
    "              node_color_list=color_list_114)\n",
    "\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/input_output_analysis_aus_114.pdf\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a3095a50",
   "metadata": {},
   "source": [
    "### GDP growth rates and std. deviations (in parentheses) for 8 countries\n",
    "\n",
    "Here we load a `pandas` DataFrame of GDP growth rates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e7aa80e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "gdp_df = ch2_data['gdp_df']\n",
    "gdp_df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c82df9d4",
   "metadata": {},
   "source": [
    "Now we plot the growth rates and calculate their standard deviations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "394a86ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "fig, axes = plt.subplots(5, 2, figsize=(8, 9))\n",
    "axes = axes.flatten()\n",
    "\n",
    "countries = gdp_df.columns\n",
    "t = np.asarray(gdp_df.index.astype(float))\n",
    "series = [np.asarray(gdp_df[country].astype(float)) for country in countries]\n",
    "\n",
    "\n",
    "for ax, country, gdp_data in zip(axes, countries, series):\n",
    "    \n",
    "    ax.plot(t, gdp_data)\n",
    "    ax.set_title(f'{country} (${gdp_data.std():1.2f}$\\%)' )\n",
    "    ax.set_ylabel('\\%')\n",
    "    ax.set_ylim((-12, 14))\n",
    "\n",
    "plt.tight_layout()\n",
    "if export_figures:\n",
    "    plt.savefig(\"figures/gdp_growth.pdf\")\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
